﻿using System;
using System.Collections;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Framework.Model;
using Framework.Sql;

namespace Framework.Metadata
{
    public class ColumnPropertyMetadata : PropertyMetadataBase, ISelectSqlBuilderModifier, IInsertSqlBuilderModifier
    {
        public string ColumnName { get; private set; }

        public ColumnPropertyMetadata(PropertyInfo propertyInfo)
        {
            PropertyInfo = propertyInfo;

            var defaultColumnName = new NamingConventionConverter().ConvertName(propertyInfo.Name);
            if (typeof(IId).GetProperties().Single().Name == propertyInfo.Name)
                defaultColumnName = string.Format("{0}_{1}", TypeMetadata.FromType(propertyInfo.DeclaringType).TableName, defaultColumnName);
            else if (propertyInfo.PropertyType.Namespace != null &&  !propertyInfo.PropertyType.Namespace.StartsWith("System"))
                defaultColumnName += "_id";

            ColumnName = defaultColumnName;
        }

        public void ModifySql(SelectSqlBuilder builder)
        {
            builder.AddSelectColumn(ColumnName);
        }

        public override void UpdateObject(object o, IDataRecord record, Func<Type, LambdaExpression, Action<SelectSqlBuilder, Type>, IEnumerable> find)
        {
            var value = record[ColumnName];
            if (value == DBNull.Value) return;

            if (value != null && value.GetType() == typeof(decimal))
                value = Convert.ToDouble(value);
            PropertyInfo.SetValue(o, value, null);
        }

        public virtual void ModifySql(InsertSqlBuilder builder, object value)
        {
            builder.AddUpdateColumn(ColumnName, PropertyInfo.GetValue(value, null));
        }
    }
}